package com.reebake.ideal.message.websocket.config;

import java.util.List;
import java.util.Map;

import com.reebake.ideal.constants.CommonConstants;
import com.reebake.ideal.crypto.util.JwtUtil;
import com.reebake.ideal.message.websocket.core.WebsocketConstants;
import com.reebake.ideal.message.websocket.core.WebsocketServer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import cn.hutool.core.collection.CollectionUtil;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;
import lombok.extern.slf4j.Slf4j;

@Configuration
@Slf4j
public class WebsocketServerConfig extends ServerEndpointConfig.Configurator {

	@Bean
    ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Bean
    WebsocketServer websocketServer() {
        return new WebsocketServer();
    }

    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        final Map<String, Object> userProperties = sec.getUserProperties();
        // websocket无法携带header，选择url参数进行传递
        Map<String, List<String>> headers = request.getParameterMap();

        String userId = null;
        // 获取头中的token
        String bearerToken = CollectionUtil.get(headers.get(HttpHeaders.AUTHORIZATION), 0);
        if (!StringUtils.hasText(bearerToken)) {
            // 会话编号当用户编号
            userId = CollectionUtil.get(headers.get(WebsocketConstants.HEADER_NAME_SESSION_ID), 0);
            if(!StringUtils.hasText(userId)) {
                log.error("没有携带token或会话编号，不允许进行连接.");
                throw new IllegalArgumentException("UNAUTHORIZED");
            }
        }else {
            userId = JwtUtil.getUserId(bearerToken);
        }
        userProperties.put(CommonConstants.ATTRIBUTE_NAME_USER_ID, userId);
    }
}
